import * as THREE from 'three';

// Orbit controls（轨道控制器）可以使得相机围绕目标进行轨道运动
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'


const scene = new THREE.Scene();

const camera = new THREE.PerspectiveCamera( 75, 1.0 , 0.1, 1000 );
// 将视觉移到立方体中心，并让贴图内翻转一下，就能实现全景看房
camera.position.set(-25,8,-15);
camera.lookAt(0, 0, 0);


const renderer = new THREE.WebGLRenderer({ antialias: true }); 

const windowInfo = {
	width: window.innerWidth,
  height: window.innerHeight,
}

renderer.setSize( windowInfo.width, windowInfo.height );
document.body.appendChild( renderer.domElement )


const textureLoader = new THREE.TextureLoader()

// 右左 上下 前后  人站在房子里面的视角观看
const images = [
	'./view-house/right.jpg', 
	'./view-house/left.jpg',
	'./view-house/top.jpg',
	'./view-house/bottom.jpg',
	'./view-house/front.jpg', 
	'./view-house/back.jpg',
]
let materials = [] //存储不同面的贴图
images.forEach(imgUrl => {
	const texture = textureLoader.load(imgUrl)
	const material = new THREE.MeshBasicMaterial( { 
		map: texture,
	} )
	materials.push(material)
})

// 2、创建球体  实现看房--需要全景图
// 2.1 客厅
const sphereTexture = textureLoader.load('./view-house/scene.jpg')
const sphereMaterial = new THREE.MeshBasicMaterial({
	map: sphereTexture
})
const sphere = new THREE.Mesh(
	new THREE.SphereGeometry(16,32,32), 
  sphereMaterial
)
sphere.geometry.scale(8, 8, -8)
scene.add(sphere)

// 点精灵---卧室1
const enterBedroom1Texture = textureLoader.load('./view-house/enterBedroom1.png')
const bedroom1SpriteMmaterial = new THREE.SpriteMaterial({
	map: enterBedroom1Texture,
	name: 'bedroom1'
})
const bedroom1Sprite = new THREE.Sprite(bedroom1SpriteMmaterial)
bedroom1Sprite.scale.set(6, 3, 1)
bedroom1Sprite.position.set(3,0,40)
scene.add(bedroom1Sprite)

// 点精灵---卧室2
const enterBedroom2Texture = textureLoader.load('./view-house/enterBedroom2.png')
const bedroom2SpriteMmaterial = new THREE.SpriteMaterial({
	map: enterBedroom2Texture,
	name: 'bedroom2'
})
const bedroom2Sprite = new THREE.Sprite(bedroom2SpriteMmaterial)
bedroom2Sprite.scale.set(6, 3, 1)
bedroom2Sprite.position.set(43,0,40)
scene.add(bedroom2Sprite)

// 点精灵---大厅
const sceneTexture = textureLoader.load('./view-house/enterScene.png')
const sceneSpriteMmaterial = new THREE.SpriteMaterial({
	map: sceneTexture,
	name: 'livingRoom'
})
const sceneSprite = new THREE.Sprite(sceneSpriteMmaterial)
sceneSprite.material = sceneSpriteMmaterial
sceneSprite.scale.set(6, 3, 1)
sceneSprite.position.set(-20,-1,-80)

// 获取tips元素
let tipsDom = document.querySelector('.tips')

let mouse = new THREE.Vector2()
const raycaster = new THREE.Raycaster();

let currenScene = 'livingRoom'

// 鼠标悬浮在精灵图上时显示进入文字
renderer.domElement.addEventListener('mousemove', (e) => {
	// 将屏幕坐标归一化为设备坐标, x,y的方向取值范围-1到1
	mouse.x = (e.clientX / windowInfo.width) * 2 - 1;
  mouse.y = -(e.clientY / windowInfo.height) * 2 + 1;

  // 射线检测
	// 通过摄像机和鼠标位置更新射线
  raycaster.setFromCamera(mouse, camera);

  // 射线检测结果
  const intersects = raycaster.intersectObjects([bedroom1Sprite, bedroom2Sprite, sceneSprite]);
	// console.log(intersects);
  if (intersects.length > 0) {
		// 世界坐标  三维空间中的点
		const worldPosition = new THREE.Vector3(
			intersects[0].object.position.x,
			intersects[0].object.position.y,
			intersects[0].object.position.z,
		)
		// 将世界坐标转为设备坐标  将此向量(坐标)从世界空间投影到相机的标准化设备坐标 (NDC) 空间
		const devicePosition = worldPosition.project(camera)
		// 将设备坐标(-1到1)转为屏幕坐标(0-w,0-h)
		const halfW = windowInfo.width / 2
		const halfH = windowInfo.height / 2

		const tipsDomRect = tipsDom.getBoundingClientRect()
		
		const screenLeft = devicePosition.x * halfW + halfW
		const screenTop = -devicePosition.y * halfH + halfH - tipsDomRect.height

		tipsDom.style.display = 'block'
		tipsDom.style.top = screenTop + 'px'
		tipsDom.style.left = screenLeft + 'px'
  } else {
		tipsDom.style.display = 'none'
		tipsDom.style.top = 0
		tipsDom.style.left = 0
  }
})
// 鼠标点击进入
renderer.domElement.addEventListener('mousedown', (e) => {
	// 将屏幕坐标归一化为设备坐标, x,y的方向取值范围-1到1
	mouse.x = (e.clientX / windowInfo.width) * 2 - 1;
  mouse.y = -(e.clientY / windowInfo.height) * 2 + 1;

  // 射线检测
	// 通过摄像机和鼠标位置更新射线
  raycaster.setFromCamera(mouse, camera);

  // 射线检测结果
  const intersects = raycaster.intersectObjects([bedroom1Sprite, bedroom2Sprite, sceneSprite]);
	console.log(intersects);
	
	if (intersects.length) {
		if (currenScene === 'livingRoom') {
			let bedroomSphereMaterial
			if (intersects[0].object.material.name === 'bedroom1') { // 进入卧室1
				const bedroomSphereTexture = textureLoader.load('./view-house/bedroom.jpg')
				 bedroomSphereMaterial = new THREE.MeshBasicMaterial({
					map: bedroomSphereTexture,
					name: 'bedroom1'
				})
				sceneSprite.position.set(-40,-10,-80)
				// 点精灵切换---单个
				// bedroom1Sprite.material = sceneSpriteMmaterial
				// bedroom1Sprite.position.set(-20,-1,-80)
				// bedroom1Sprite.scale.set(6, 3, 1)

				// removeSprite = bedroom2Sprite
			}else if (intersects[0].object.material.name === 'bedroom2') { // 进入卧室2
				const bedroomSphereTexture = textureLoader.load('./view-house/bedroom2.jpg')
				bedroomSphereMaterial = new THREE.MeshBasicMaterial({
					map: bedroomSphereTexture,
					name: 'bedroom2'
				})
				// 点精灵切换
				// bedroom2Sprite.material = sceneSpriteMmaterial
				// bedroom2Sprite.position.set(-20,-1,-80)
				// bedroom2Sprite.scale.set(6, 3, 1)

				// removeSprite = bedroom1Sprite
			}
			// 切换场景
			sphere.material = bedroomSphereMaterial
			// 移除场景中的物体
			scene.remove(bedroom1Sprite, bedroom2Sprite)
			scene.add(sceneSprite)
			currenScene = 'bedroom'
		}else if (currenScene === 'bedroom') {
			sphere.material = sphereMaterial
			scene.add(bedroom1Sprite, bedroom2Sprite)
			scene.remove(sceneSprite)
			currenScene = 'livingRoom'
		}
	}

})
//辅助观察的坐标系
const axesHelper = new THREE.AxesHelper(1000);
// 设置x,y,z轴的颜色
axesHelper.setColors(new THREE.Color(0xff0000), new THREE.Color(0x00ff00), new THREE.Color('pink'))
// scene.add(axesHelper);


// 控制器的使用
// 控制器实例化  参数：相机  绑定事件的元素
const controls = new OrbitControls( camera, renderer.domElement );

//controls.update() must be called after any manual changes to the camera's transform
controls.enableDamping = true //启用惯性


controls.addEventListener('change', () => {
  renderer.render( scene, camera )
  console.log(camera.position);
  
})

const clock = new THREE.Clock();
function animate(){
	const elapsedTime = clock.getDelta()
	controls.update();
	requestAnimationFrame(animate);
  renderer.render(scene, camera);
}
animate()